﻿//#define _CRT_SECURE_NO_WARNINGS 1
//#include<stdio.h>
////int main()
////{
////	char* pstr = "hello";
////	*pstr = "hehe";
////	printf("%s\n", pstr);
////	return 0;
////}
//
////#include <stdio.h>
////int main()
////{
////	char str1[] = "hello bit.";
////	char str2[] = "hello bit.";
////	const char* str3 = "hello bit.";
////	const char* str4 = "hello bit.";
////	if (str1 == str2)
////		printf("str1 and str2 are same\n");
////	else
////		printf("str1 and str2 are not same\n");
////
////	if (str3 == str4)
////		printf("str3 and str4 are same\n");
////	else
////		printf("str3 and str4 are not same\n");
////
////	return 0;
////}
//
//
////#include <stdio.h>
////int main()
////{
////	int arr[10] = { 0 };
////	printf("arr = %p\n", arr);
////	printf("&arr= %p\n", &arr);
////
////	printf("arr+1 = %p\n", arr + 1);
////	printf("&arr+1= %p\n", &arr + 1);
////	return 0;
////}
//
////#include<stdio.h>
////int main()
////{
////	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
////	int(*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p
////	//但是我们一般很少这样写代码
////	return 0;
////}
//
////#include <stdio.h>
////void print_arr1(int arr[3][5], int row, int col) {
////	int i = 0;
////	for (i = 0; i < row; i++)
////	{
////		int j = 0;
////		for (j = 0; j < col; j++)
////		{
////			printf("%d ", arr[i][j]);
////		}
////		printf("\n");
////	}
////}
////void print_arr2(int(*arr)[5], int row, int col) {
////	int i = 0;
////	for (i = 0; i < row; i++)
////	{
////		int j = 0;
////		for (j = 0; j < col; j++)
////		{
////			printf("%d ", arr[i][j]);
////		}
////		printf("\n");
////	}
////}
////int main()
////{
////	int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
////	print_arr1(arr, 3, 5);
////	//数组名arr，表示首元素的地址
////	//但是二维数组的首元素是二维数组的第一行
////	//所以这里传递的arr，其实相当于第一行的地址，是一维数组的地址
////	//可以数组指针来接收
////	print_arr2(arr, 3, 5);
////	return 0;
////}
//
////#include <stdio.h>
////void test(int arr[])
////{}
////void test(int arr[10])
////{}
////void test(int* arr)//*表示要接收的形参类型为指针，指向的类型为int
////{}
////void test2(int* arr[20])
////{}
////void test2(int** arr)//第二个*表示接收的形参类型为指针，
////                     //第一个*和int结合表示指向的类型为int*
////{}
////
////int main()
////{
////	int arr[10] = { 0 };
////	int* arr2[20] = { 0 };
////	test(arr);
////	test2(arr2);
////}
//
////void test(int arr[3][5])
////{}
////void test(int arr[][5])
////{}
//////总结：二维数组传参，函数形参的设计只能省略第一个[]的数字。
//////因为对一个二维数组，可以不知道有多少行，但是必须知道一行多少元素。
//////这样才方便运算。
////void test(int(*arr)[5])//ok？
////{}
//////接收数组时用数组指针接收
////
////int main()
////{
////	int arr[3][5] = { 0 };
////	test(arr);
////}
//
////#include <stdio.h>
////void print(int* p, int sz) {
////	int i = 0;
////	for (i = 0; i < sz; i++)
////	{
////		printf("%d\n", *(p + i));
////	}
////}
////int main()
////{
////	int arr[10] = { 1,2,3,4,5,6,7,8,9 };
////	int* p = arr;
////	int sz = sizeof(arr) / sizeof(arr[0]);
////	//一级指针p，传给函数
////	print(p, sz);
////	return 0;
////}
//
////#include <stdio.h>
////void test(int** ptr) 
////{
////	printf("num = %d\n", **ptr);
////}
////
////int main()
////{
////	int n = 10;
////	int* p = &n;//一级指针
////	int** pp = &p;//二级指针
////	test(pp);//二级指针传参
////	test(&p);//二级指针传参
////	return 0;
////}
//
////#include <stdio.h>
////void test()
////{
////	printf("hehe\n");
////}
////
////int main()
////{
////	printf("%p\n", test);
////	printf("%p\n", &test);
////	return 0;
////}
//
////#include<stdio.h>
////int Add(int x, int y)
////{
////	return x + y;
////}
////
////int main()
////{
////	int (*pAdd)(int x, int y) = &Add;
////	int (*pAdd)(int x, int y) = Add;//由上文可知，两种赋值形式均可行
////	return 0;
////}
//
////#include <stdio.h>
////int add(int a, int b) 
////{
////	return a + b;
////}
////int sub(int a, int b) 
////{
////	return a - b;
////}
////int mul(int a, int b) 
////{
////	return a * b;
////}
////int div(int a, int b) 
////{
////	return a / b;
////}
////
////int main()
////{
////	int x, y;
////	int input = 1;
////	int ret = 0;
////	do
////	{
////		printf("*************************\n");
////		printf(" 1:add           2:sub \n");
////		printf(" 3:mul           4:div \n");
////		printf("*************************\n");
////		printf("请选择：");
////		scanf("%d", &input);
////		switch (input)
////		{
////		case 1:
////			printf("输入操作数：");
////			scanf("%d %d", &x, &y);
////			ret = add(x, y);
////			printf("ret = %d\n", ret);
////			break;
////		case 2:
////			printf("输入操作数：");
////			scanf("%d %d", &x, &y);
////			ret = sub(x, y);
////			printf("ret = %d\n", ret);
////			break;
////		case 3:
////			printf("输入操作数：");
////			scanf("%d %d", &x, &y);
////			ret = mul(x, y);
////			printf("ret = %d\n", ret);
////			break;
////		case 4:
////			printf("输入操作数：");
////			scanf("%d %d", &x, &y);
////			ret = div(x, y);
////			printf("ret = %d\n", ret);
////			break;
////		case 0:
////			printf("退出程序\n");
////			break;
////		default:
////			printf("选择错误\n");
////			break;
////		}
////	} while (input);
////
////	return 0;
////}
//
////#include <stdio.h>
////int add(int a, int b) 
////{
////	return a + b;
////}
////int sub(int a, int b) 
////{
////	return a - b;
////}
////int mul(int a, int b) 
////{
////	return a * b;
////}
////int div(int a, int b) 
////{
////	return a / b;
////}
////
////int main()
////{
////	int x, y;
////	int input = 1;
////	int ret = 0;
////	int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
////	while (input)
////	{
////		printf("*************************\n");
////		printf(" 1:add           2:sub \n");
////		printf(" 3:mul           4:div \n");
////		printf("*************************\n");
////		printf("请选择：");
////		scanf("%d", &input);
////		if ((input <= 4 && input >= 1))
////		{
////			printf("输入操作数：");
////			scanf("%d %d", &x, &y);
////			ret = (*p[input])(x, y);
////		}
////		else
////			printf("输入有误\n");
////		printf("ret = %d\n", ret);
////	}
////	return 0;
////}
//
////#include<stdio.h>
////int main()
////{
////	int a = 3;
////	int b = ~a;
////	printf("%d", b);
////	return 0;
////}
//
//
//////需要引入的文件
////#include<stdio.h>
////#include<math.h>
//////如解答错误，注意检查错误信息提示，对比预期输出和实际输出之间的差异
////int main()
////{
////    int i = 0;
////    int cut = 0;
////    int sum = 0;
////    int j = 0;
////    int f = 1;
////
////    for (i = 799; i >=500 ; i-=2)
////    {
////        int flag = 0;
////        for (j = 2; j <= sqrt(i); j++)
////        {
////            if (i % j == 0)
////            {
////                flag = 1;
////                break;
////            }
////        }
////        if (flag==0)
////        {
////            cut++;
////            sum += i*f;
////            f = -f;
////        }
////    }
////    printf("%d %d", cut, sum);
////}
//
////#include<stdio.h>
////int main()
////{
////	int arr[5][5] = { 0 };
////	int i = 0;
////	int j = 0;
////	for (i = 0; i < 5; i++)
////	{
////		for (j = 0; j < 5; j++)
////		{
////			scanf("%d", &arr[i][j]);
////		}
////	}
////	int pro = 1;
////	int max = 0;
////	for (i = 0; i < 5; i ++)
////	{
////		if (i % 2 == 0)
////			pro *= arr[i][i];
////		if (arr[i][i] > max)
////			max = arr[i][i];
////	}
////	printf("%d %d", pro, max);
////	return 0;
////}
//
//
////#define _CRT_SECURE_NO_WARNINGS 1
////#include<string.h>
////#include<stdio.h>
////int main()
////{
////    unsigned char puc[4];
////    struct tagPIM
////    {
////        unsigned char ucPim1;
////        unsigned char ucData0 : 1;
////        unsigned char ucData1 : 2;
////        unsigned char ucData2 : 3;
////    }*pstPimData;
////    pstPimData = (struct tagPIM*)puc;
////    memset(puc, 0, 4);
////    pstPimData->ucPim1 = 2;
////    pstPimData->ucData0 = 3;
////    pstPimData->ucData1 = 4;
////    pstPimData->ucData2 = 5;
////    printf("%02x %02x %02x %02x\n", puc[0], puc[1], puc[2], puc[3]);
////    return 0;
////}
//
////int main()
////{
////	int i = 0;
////	int fac = 1;
////	int sum = 0;
////	for (i = 1; i <= 7; i++)
////	{
////		fac *= i;
////		sum += fac;
////	}
////	printf("%d", sum);
////	return 0;
////}
//
////union Un1
////{
////	char c[5];
////	int i;
////};
////union Un2
////{
////	short c[7];
////	int i;
////};
////
////int main()
////{
////	printf("%d\n", sizeof(union Un1));
////	printf("%d\n", sizeof(union Un2));
////	return 0;
////}
//
////int main()
////{
////    union
////    {
////        short k;
////        char i[2];
////    }*s, a;
////    s = &a;
////    s->i[0] = 0x39;
////    s->i[1] = 0x38;
////    printf(" % x\n", a.k);
////    return 0;
////}
//
////#include<stdio.h>
////int main() {
////    int N = 0;
////    scanf("%d", &N);
////    int i = 0;
////    int a = 1, b = 1;
////    while (N < a || N > b) {
////        int tmp = a + b;
////        a = b;
////        b = tmp;
////    }
////    int min1 = N - a;
////    int min2 = b - N;
////    if (min1 < min2)
////        printf("%d", min1);
////    else
////        printf("%d", min2);
////    return 0;
////}
//
////void replaceSpace(char* str, int length) {
////    int count = 0;
////    char* p = str;
////    char arr[4] = "%20";
////    while (*p)
////    {
////        if (*p == ' ')
////        {
////            memmove(p + 2, p, length - count);
////            memcpy(p, arr, 3);
////        }
////        p++;
////        count++;
////    }
////}
////
////int main()
////{
////    char str[1000] = "are you ok.";
////    //replaceSpace(str, 11);
////    int count = 0;
////    char* p = str;
////    char arr[4] = "%20";
////    while (*p)
////    {
////        if (*p == ' ')
////        {
////            memmove(p + 2, p, 11 - count);
////            memcpy(p, arr, 3);
////            p += 3;
////        }
////        p++;
////        count++;
////    }
////    printf("%s", str);
////    return 0;
////}
//
//
//#include<stdio.h>
//#include<math.h>
//void is_prime(int n)
//{
//	int flag = 0;
//	int  i = 0;
//	for ( i = 2; i <= sqrt(n); i++)
//	{
//		if (n % i == 0)
//		{
//			flag = 1;
//			break;
//		}
//	}
//	if (i> sqrt(n))
//		printf("%d ", n);
//}
//int main()
//{
//	int i = 0;
//	for (i = 100; i <= 200; i++)
//	{
//		is_prime(i);
//	}
//	return 0;
//}



#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
typedef char STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 栈顶
	int capacity;  // 容量 
}Stack;

// 初始化栈 
void StackInit(Stack* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)//每次使用malloc类函数都要检查是都申请内存成功
	{
		perror("fail malloc.");
		exit(-1);
	}
	ps->top = 0;
	ps->capacity = 4;
}

//入栈
void StackPush(Stack* ps, STDataType x)
{
	assert(ps);
	if (ps->capacity == ps->top)
	{
		//注意细节，记得强转
		STDataType* tps = (STDataType*)realloc(ps->a, 2 * ps->capacity * sizeof(STDataType));
		if (tps == NULL)
		{
			perror("fail realloc.");
			exit(-1);//perror和exit相绑定
		}
		ps->a = tps;
		//ps->capacity = ps->capacity * 2;
		ps->capacity *= 2;
	}
	ps->a[ps->top] = x;
	ps->top++;
}


// 出栈
void StackPop(Stack* ps)
{
	assert(ps);
	//assert(ps->top);
	assert(!StackEmpty(ps));

	ps->top--;
}

// 获取栈顶元素
STDataType StackTop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->a[ps->top - 1];//注意使用是不能用自减来实现，会改变自生值
}

// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}

// 检测栈是否为空，如果为空返回非零结果，如果不为空返回0 
int StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->top == 0;
}

// 销毁栈
void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->a);//只有ps->a是malloc的释放内存只要释放ps->a，而不是ps
	ps->a = NULL;//freeÿ
	ps->top = ps->capacity = 0;
}


//int maxDepth(char* s)
//{
//	Stack st;
//	StackInit(&st);
//	int count = 0;
//	int max = 0;
//	int i = 0;
//	while (s[i] = '\0')
//	{
//		if (s[i] == '(')
//		{
//			StackPush(&st, '(');
//			count++;
//		}
//		if (s[i] == ')')
//		{
//			if (count > max)
//			{
//				max = count;
//			}
//			StackPop(&st);
//			count--;
//		}
//		i++;
//	}
//	return max;
//}

char* makeGood(char* s)
{
	Stack st;
	StackInit(&st);
	char* cur = s;
	while (*cur)
	{
		StackPush(&st, *cur);
		cur++;
		while (!StackEmpty(&st) &&
			((StackTop(&st) == (*cur) + 32) ||
				(StackTop(&st) == (*cur) - 32)))
		{
			cur++;
			StackPop(&st);
		}
	}
	int len = StackSize(&st);
	s[len] = '\0';
	int i = len - 1;
	while (!StackEmpty(&st))
	{
		s[i] = StackTop(&st);
		StackPop(&st);
		i--;
	}
	return s;
}

int main()
{
	char s[] = "abBAcC";
	makeGood(s);
}